#!/usr/bin/env python3
print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
print("++                                                           ++")
print("++                       2048数字游戏                        ++")
print("++                                                           ++")
print("++           Ver:0.1    Author:ycjnx    2017.12              ++")
print("++                                                           ++")
print("++  k：向上；j：向下；h：向左；l：向右；q：退出；要加回车键  ++")
print("++                                                           ++")
print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
import random
class game:
    #kong=[[0,0] for i in range(16)]
    #生成一个随机数：2或4
    def num(self):
        return random.choice([2,4])
    #查找一个随机的空位置的坐标：
    def kongzb(self):
        if(len(self.kong)>0):
            index=random.randint(0,len(self.kong)-1)
            return index
        return -1
    #游戏开始，初始化棋盘
    def __init__(self):
        self.qipaninit()
        #开始游戏
        self.main()
    def qipaninit(self):
        self.success=False
        #棋盘数据初始化
        self.qipan=[[0,0,0,0] for i in range(4)]
        #空位置数组，存储空位置的坐标：
        self.kong=[[0,0] for i in range(16)]
        self.oldkey=""
        self.count=0
        #将所有的位置都加入到空位置列表中：
        i=0
        for j in range(0,4):
            for k in range(0,4):
                self.kong[i][0]=j
                self.kong[i][1]=k
                i+=1
        #给随机的位置上给出两个随机数：2和4
        self.setvalue(self.kongzb(),self.num())
        self.setvalue(self.kongzb(),self.num())
        #测试专用
        self.setvalue(self.kongzb(),8)
        self.setvalue(self.kongzb(),16)
        self.setvalue(self.kongzb(),self.num())
        self.setvalue(self.kongzb(),self.num())
        self.setvalue(self.kongzb(),8)
        self.setvalue(self.kongzb(),16)
        self.setvalue(self.kongzb(),self.num())
        self.setvalue(self.kongzb(),self.num())
        self.setvalue(self.kongzb(),8)
        self.setvalue(self.kongzb(),16)
        self.setvalue(self.kongzb(),self.num())
        self.setvalue(self.kongzb(),self.num())
        self.setvalue(self.kongzb(),8)
        self.setvalue(self.kongzb(),16)
        #画棋盘
        self.qipanprint()
    #输出棋盘
    def qipanprint(self):         
        self.count+=1
        print(self.count)
        print("------------------------------------")
        for j in range(0,4):
            for k in range(0,4):
                print(str(self.qipan[j][k]),end="       ")
            print()
        print("------------------------------------")
    #给坐标设置值
    def setvalue(self,index,value):
        if(index> -1):
            zuobiao=self.kong[index]
            self.qipan[zuobiao[0]][zuobiao[1]]=value
            if(value>0):
                del self.kong[index]
    def main(self):
        a=input()
        while(a!="q"):
            if(self.oldkey!=a):
                norun=False
                if(a=="j"):
                    self.down()
                elif(a=="k"):
                    self.up()
                elif(a=="h"):
                    self.left()
                elif(a=="l"):
                    self.right()
                elif(a=="r"):
                    print("重新开始")
                    self.qipaninit()
                    norun=True
                    self.oldkey=a
                else:
                    norun=True
                if not norun:
                    self.oldkey=a
                    if self.kongsum():
                        #在随机的位置上给出一个随机数：2和4
                        self.setvalue(self.kongzb(),self.num())
                        self.qipanprint()
                        #没有空位时旋转90度检查是否有可以合并项
                    elif not self.check90():
                        print("游戏结束，请按r键重新开始，或按q键退出")
                    elif self.success:
                        print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
                        print("++                                                           ++")
                        print("++                       祝贺你！你是王者！                  ++")
                        print("++                                                           ++")
                        print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
                        print("请按r键重新开始，或按q键退出")
            a=input()      
    def check90(self):
        goon=False
        if self.oldkey=="j" or self.oldkey=="k":
            a=[0,0,0,0]
            for i in range(0,4):
                k= 0
                for j in range(0,4):
                    a[k]=self.qipan[i][j]
                    k+= 1
                if self.checksame(a):
                    goon=True
                    break
        elif self.oldkey=="h" or self.oldkey=="l":
            a=[0,0,0,0]
            for i in range(0,4):
                k= 0
                for j in range(0,4):
                    a[k]=self.qipan[j][i]
                    k+= 1
                if self.checksame(a):
                    goon=True
                    break
        return goon
    def down(self):
        print("向下移")
        a=[0,0,0,0]
        for i in range(0,4):
            k= 0
            for j in range(3,-1,-1):
                a[k]=self.qipan[j][i]
                k+= 1
            a=self.do4(a)
            k= 0
            for j in range(3,-1,-1):
                self.qipan[j][i]=a[k]
                k+= 1
    def up(self):
        print("向上移")
        a=[0,0,0,0]
        for i in range(0,4):
            for j in range(0,4):
                a[j]=self.qipan[j][i]
            a=self.do4(a)
            for j in range(0,4):
                self.qipan[j][i]=a[j]
    def right(self):
        print("向右移")
        a=[0,0,0,0]
        for i in range(0,4):
            k= 0
            for j in range(3,-1,-1):
                a[k]=self.qipan[i][j]
                k+= 1
            a=self.do4(a)
            k= 0
            for j in range(3,-1,-1):
                self.qipan[i][j]=a[k]
                k+= 1
    def left(self):
        print("向左移")
        a=[0,0,0,0]
        for i in range(0,4):
            for j in range(0,4):
                a[j]=self.qipan[i][j]
            a=self.do4(a)
            for j in range(0,4):
                self.qipan[i][j]=a[j]
    #处理一组4个数字
    def do4(self,a):
        temp=[0,0,0,0]
        runflag=False
        #将所有非0项前移
        j=0
        for i in range(0,4):
            if(a[i]>0):
                temp[j]=a[i]
                j+=1
                runflag=True
        a=temp
        if(runflag):
            while self.checksame(a):
                #合并相邻的相同数
                if(a[0]==a[1]):
                    a[0]+=a[1]
                    a[1]=a[2]
                    a[2]=a[3]
                    a[3]=0
                if(a[1]==a[2]):
                    a[1]+=a[2]
                    a[2]=a[3]
                    a[3]=0
                if(a[2]==a[3]):
                    a[2]+=a[3]
                    a[3]=0
        #print(a)
        return a 
    #检查相邻是否有相同的非零数字
    def checksame(self,a):
        havesame=False
        for i in range(1,len(a)-1):
            if a[i]>0 and a[i-1]==a[i]:
                havesame=True
                break
        return havesame
    #统计当前的空位
    def kongsum(self):
        #空位置数组，存储空位置的坐标：
        self.kong=[[0,0] for i in range(16)]
        i=0
        delstr=""
        for j in range(0,4):
            for k in range(0,4):
                num=self.qipan[j][k]
                if(num==0):
                    self.kong[i][0]=j
                    self.kong[i][1]=k
                else:
                    if(num>=2048):
                        self.success=True
                    delstr+=","+str(i)
                i+=1
        #print(self.kong)
        if(delstr!=""):
            delstr=delstr[1:]
            #print(delstr)
            delarr=delstr.split(",")
            #print(delarr)
            #print(self.kong)
            for i in range(len(delarr)-1,-1,-1):
                del self.kong[int(delarr[i])]
        if(len(self.kong)>0):
            return True
        else:
            return False
        #print(self.kong)

g=game()
